﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media;
using System.Diagnostics;
using System.Windows.Media.Imaging;
using Microsoft.Surface.Presentation.Controls;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Master
{
    /*
     * NpOutgoing is used to the define the outgoing point for the networkprotocol.
     * This outgoing point is preset while setting up the roads.
     * It contains properties for the status and the orientation.
     * 
     * @Creator: T.T. Dusseldorp
     * @Changes made by:
     *      - A.J. Janssen
     *      - V.L. de Jager
     */
    public class NpOutgoing : Label
    {
        /*************
         * VARIABLES *
         *************/
        private Client client = null;
        public bool menuActive = false;
        /*************************
         * DEPENDENCY PROPERTIES *
         *************************/
        public static readonly DependencyProperty statusProperty, orientationProperty;

        public NpOutgoingStatus Status
        {
            set { SetValue(statusProperty, value); }
            get { return (NpOutgoingStatus)GetValue(statusProperty); }
        }

        public int Orientation
        {
            set { SetValue(orientationProperty, value); }
            get { return (int)GetValue(orientationProperty); }
        }

        private static void orientationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }

        private static void statusPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NpOutgoing npOutgoing = (NpOutgoing)d;
            NpOutgoingStatus newValue = (NpOutgoingStatus)e.NewValue;
            if (newValue == NpOutgoingStatus.DISABLED)
            {
                npOutgoing.client = null;

                Color c = Colors.Red;
                turnLaneToColor(npOutgoing, c);
            }
            if (newValue == NpOutgoingStatus.ENABLED)
            {
                Color c = Colors.LightGreen;
                turnLaneToColor(npOutgoing, c);
            }
        }

        private static void turnLaneToColor(NpOutgoing npOutgoing, Color newColor)
        {
            LinearGradientBrush myVerticalGradient = new LinearGradientBrush();
            switch (npOutgoing.Orientation)
            {
                case 0:

                    myVerticalGradient.StartPoint = new Point(0.5, 1);
                    myVerticalGradient.EndPoint = new Point(0.5, 0);

                    break;
                case 90:

                    myVerticalGradient.StartPoint = new Point(0, 0.5);
                    myVerticalGradient.EndPoint = new Point(1, 0.5);

                    break;
                case 180:

                    myVerticalGradient.StartPoint = new Point(0.5, 0);
                    myVerticalGradient.EndPoint = new Point(0.5, 1);

                    break;
                case 270:

                    myVerticalGradient.StartPoint = new Point(1, 0.5);
                    myVerticalGradient.EndPoint = new Point(0, 0.5);

                    break;
            }
            if (npOutgoing != null)
            {
                myVerticalGradient.GradientStops.Add(
                    new GradientStop(Colors.Gray, 0.6));
                myVerticalGradient.GradientStops.Add(
                    new GradientStop(newColor, 0.99));

                // Use the brush to paint the rectangle.
                npOutgoing.Background = myVerticalGradient;
            }
        }

        /**********************
         * STATIC CONSTRUCTOR *
         **********************/

        /*
         * Inside this static constructor all metadata and events will be set for the depency properties. 
         */
        static NpOutgoing()
        {
            //CREATE DEPENDENCY PROPERTY METADATA
            FrameworkPropertyMetadata orientationPropertyMetadata = new FrameworkPropertyMetadata(0,
                new PropertyChangedCallback(NpOutgoing.orientationPropertyChanged));
            FrameworkPropertyMetadata statusPropertyMetadata = new FrameworkPropertyMetadata(NpOutgoingStatus.DISABLED,
                new PropertyChangedCallback(NpOutgoing.statusPropertyChanged));
            //REGISTER DEPENDENCY PROPERTIES
            statusProperty = DependencyProperty.Register("Status", typeof(NpOutgoingStatus), typeof(NpOutgoing), statusPropertyMetadata);
            orientationProperty = DependencyProperty.Register("Orientation", typeof(int), typeof(NpOutgoing), orientationPropertyMetadata);
        }

        /***************
         * CONSTRUCTOR *
         ***************/

        /*
         * Public constructor used to set up the events
         */
        public NpOutgoing()
        {
            this.TouchDown += Clicked;
            this.MouseUp += Clicked;
        }

        /******************
         * INITIALIZATION *
         ******************/

        /**********
         * EVENTS *
         **********/
        void Clicked(object sender, EventArgs e)
        {
            if (!menuActive)
            {
                double x = Canvas.GetLeft(this);
                double y = Canvas.GetTop(this);
                CtrlIpinput ctrlIpinput = new CtrlIpinput(this);
                switch (Orientation)
                {
                    case 0:
                        y += 450;
                        break;
                    case 90:
                        x -= 600;
                        break;
                    case 180:
                        y -= 300;
                        break;
                    case 270:
                        x += 300;
                        break;
                }
                Canvas.SetLeft(ctrlIpinput, x);
                Canvas.SetTop(ctrlIpinput, y);
                Map.INSTANCE.Children.Add(ctrlIpinput);
                Canvas.SetZIndex(ctrlIpinput, 7);
                menuActive = true;
            }
        }

        /********************
         * PUBLIC FUNCTIONS *
         ********************/

        public void setClient(Client client)
        {
            this.client = client;
        }

        public Client getClient()
        {
            return this.client;
        }
    }
}
